﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.ServiceProcess;

namespace PSBReset {
    class Program {
        static void Main(string[] args) {
            var programFilesDir = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
            var pserviceBusDir = Directory.GetDirectories(programFilesDir)
                .FirstOrDefault(x => x.IndexOf("PServiceBus", StringComparison.OrdinalIgnoreCase) > 0);
            
            if (String.IsNullOrWhiteSpace(pserviceBusDir)) {
                Console.WriteLine("Could not find any installation of PServiceBus on this machine. Press enter to exit");
                Console.ReadLine();
                return;
            }

            var services = ServiceController.GetServices();

            var serviceMonitor = services.FirstOrDefault(x => 
                x.ServiceName.IndexOf("PServiceBus.ServiceMonitor", StringComparison.OrdinalIgnoreCase) >= 0);

            var redisService = services.FirstOrDefault(x =>
                x.ServiceName.IndexOf("PServiceBus.Redis Server", StringComparison.OrdinalIgnoreCase) >= 0);

            var psbServices = services.Where(x =>
                !(x.ServiceName.IndexOf("PServiceBus.ServiceMonitor", StringComparison.OrdinalIgnoreCase) >= 0 ||
                x.ServiceName.IndexOf("PServiceBus.Redis Server", StringComparison.OrdinalIgnoreCase) >= 0) &&
                x.ServiceName.StartsWith("PServiceBus.")
                ).ToList();

            var hasRedis = Directory.Exists(String.Format("{0}/Redis Server/", pserviceBusDir)) && redisService != null;

            Console.WriteLine("Stopping PServiceBus.Monitor Service");
            if (serviceMonitor.Status != ServiceControllerStatus.Stopped)
                serviceMonitor.Stop();
            serviceMonitor.WaitForStatus(ServiceControllerStatus.Stopped);
            Console.WriteLine("Stopping PServiceBus.Monitor Service Completed");

            Console.WriteLine("Stopping all PServiceBus Services");
            psbServices.AsParallel().ForAll(x => {
                if (x.Status != ServiceControllerStatus.Stopped)
                    x.Stop();
                x.WaitForStatus(ServiceControllerStatus.Stopped);
            });
            Console.WriteLine("Stopping PServiceBus Services Completed");

           
            if (hasRedis) {

                Console.WriteLine("Stopping PServiceBus.Redis Server");
                if (redisService.Status != ServiceControllerStatus.Stopped)
                    redisService.Stop();
                redisService.WaitForStatus(ServiceControllerStatus.Stopped);
                Console.WriteLine("Stopping PServiceBus.Redis Server Completed");

                Console.WriteLine("Clearing Redis database files");
                var redisFiles = Directory.GetFiles(String.Format("{0}/Redis Server/",
                    pserviceBusDir), "*.rdb", SearchOption.TopDirectoryOnly).ToList();

                redisFiles.ForEach(x =>
                {
                    try { File.Delete(x); } catch { }
                });

                Console.WriteLine("Clearing Redis database files Completed");

                Console.WriteLine("Starting PServiceBus.Redis Server");
                if (redisService.Status != ServiceControllerStatus.Running)
                    redisService.Start();
                redisService.WaitForStatus(ServiceControllerStatus.Running);
                Console.WriteLine("Starting PServiceBus.Redis Server Completed");
            }

            Console.WriteLine("Starting PServiceBus.Monitor Service");
            if (serviceMonitor.Status != ServiceControllerStatus.Running)
                serviceMonitor.Start();
            serviceMonitor.WaitForStatus(ServiceControllerStatus.Running);
            Console.WriteLine("Starting PServiceBus.Monitor Service Completed");

            Console.WriteLine("Waiting for all PServiceBus Services to Start");
            psbServices.AsParallel().ForAll(x =>
            {
                x.WaitForStatus(ServiceControllerStatus.Running);
            });

            Console.WriteLine("PServiceBus Reset Successfully. Press enter to exit");
            Console.ReadLine();
        }
    }
}
